﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using nRoute.Components.Bindings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;

namespace nRoute.Behaviors.Interactivity
{
    public class TriggerBase
        : AttachableCollection<TriggerAction>
    {
        private Dictionary<DependencyProperty, BindingInfo> _pendingBindings;

        public event EventHandler<PreviewInvokeEventArgs> PreviewInvoke;

#region Actions Related

        protected void InvokeActions(object parameter)
        {
            var _invokeEventArgs = new PreviewInvokeEventArgs();
            if (PreviewInvoke != null) this.PreviewInvoke(this, _invokeEventArgs);

            if (!_invokeEventArgs.Cancelling && this.Count != 0)
            {
                foreach (TriggerAction _action in this)
                {
                    _action.InvokeInternal(parameter);
                }
            }
        }

#endregion

#region Binding Helpers
        
        protected void SetBinding<P>(DependencyProperty bindingProperty, Binding value)
        {
            SetBinding(bindingProperty, typeof(P), value);
        }

        protected void SetBinding(DependencyProperty bindingProperty, Type bindingType, Binding value)
        {
            if (this.AssociatedObject != null)
            {
                this.SetAttachedBinding(AssociatedObject, bindingProperty, bindingType, value);
            }
            else
            {
                if (_pendingBindings == null)
                    _pendingBindings = new Dictionary<DependencyProperty, BindingInfo>();
                _pendingBindings.Add(bindingProperty,
                    new BindingInfo() { BindingProperty = bindingProperty, BindingType = bindingType, Binding = value });
            }
        }

        protected Binding GetBinding(DependencyProperty bindingProperty)
        {
            if (this.AssociatedObject != null)
            {
                return this.GetAttachedBinding(bindingProperty);
            }
            else if (_pendingBindings != null && _pendingBindings.ContainsKey(bindingProperty))
            {
                return _pendingBindings[bindingProperty].Binding;
            }
            else
            {
                return null;
            }
        }

        protected void ApplyAllPendingBindings()
        {
            if (_pendingBindings == null || _pendingBindings.Count == 0) return;

            // set all bindings
            foreach (var _bindingInfo in _pendingBindings.Values)
            {
                this.SetAttachedBinding(AssociatedObject, _bindingInfo);
            }

            // clear the pending
            _pendingBindings.Clear();
            _pendingBindings = null;
        }

        protected void ClearAllBindings()
        {
            if (_pendingBindings != null) _pendingBindings = null;

            // using binding on self, as opposed to attached bindings, hence disabled this (24-6-2012)
            this.ClearAttachedBindings();
        }

#endregion

#region Trigger Related

        protected override void OnAttached()
        {
            base.OnAttached();
            ApplyAllPendingBindings();
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            ClearAllBindings();
        }

#endregion

    }
}